from re import I
import sqlite3
from typing import List, Optional

from dto.stock_risk_assessment_item import AntRiskAssessmentItemDto
from .database_pool import DatabasePool
from peewee import *
from dto.stock_risk_assessment import RiskAssessmentDTO
from datetime import datetime


class AntRiskAssessmentItem(Model):
    # ID 主键，自动递增
    id = IntegerField(primary_key=True)

    # 股票代码
    stock_code = CharField(max_length=50, null=False)

    # 上传更新时间
    create_time = DateTimeField(default=datetime.now)

    # 风险描述
    description = TextField(null=True)

    # 风险类型 (例如：市场风险、流动性风险)
    risk_type = CharField(max_length=50, null=True)

    # 风险等级 (0 - 10级)
    risk_level = IntegerField(default=0)

    # 匹配标签
    stock_tag_code = CharField(max_length=50, null=True)

    # 策略 Code
    strategy_code = CharField(max_length=50, null=False)

    # 策略可读名称
    strategy_name = CharField(max_length=100, null=False)

    # 策略分组 (0: 风险型, 1: 关注型)
    strategy_group = IntegerField(
        constraints=[Check("strategy_group IN (0, 1)")], null=True
    )

    # 备用字段：策略类型
    strategy_type = CharField(max_length=50, null=True)

    # 策略分析的天数
    analysis_day = IntegerField(null=True)

    # 策略等级 (等级越高, 分数比例越高)
    strategy_level = IntegerField(null=True)

    # 最终得分
    node_point = IntegerField(null=True)

    class Meta:
        database = DatabasePool(max_connections=5).database  # 指定数据库连接
        table_name = "ant_risk_assessment_item"


class RiskAssessmentItemService:
    # 新增风险评估记录
    def add_risk_assessment_item(self, item_dto: AntRiskAssessmentItemDto):
        """
        新增风险评估记录
        :param item_dto: AntRiskAssessmentItemDto 对象
        """
        try:
            AntRiskAssessmentItem.create(
                stock_code=item_dto.stock_code,
                description=item_dto.description,
                risk_type=item_dto.risk_type,
                risk_level=int(item_dto.risk_level),  # 确保是整数
                stock_tag_code=item_dto.stock_tag_code,
                strategy_code=item_dto.strategy_code,
                strategy_name=item_dto.strategy_name,
                strategy_group=item_dto.strategy_group,
                strategy_type=item_dto.strategy_type,
                analysis_day=int(item_dto.analysis_day),  # 确保是整数
                strategy_level=int(item_dto.strategy_level),  # 确保是整数
                node_point=int(item_dto.node_point),  # 确保是整数
            )
        except ValueError as ve:
            AntLogger.info(f"字段类型转换错误: {ve}")
        except Exception as e:
            AntLogger.info(f"ant_risk_assessment_item 新增记录时出错: {e}")

    # 根据股票代码更新风险评估记录
    def update_risk_assessment_item_by_code(
        self, stock_code: str, updated_dto: AntRiskAssessmentItemDto
    ):
        """
        根据股票代码更新风险评估记录
        :param stock_code: 股票代码
        :param updated_dto: 包含要更新字段的 AntRiskAssessmentItemDto 对象
        """
        try:
            item = AntRiskAssessmentItem.get(
                AntRiskAssessmentItem.stock_code == stock_code
            )

            # 更新字段
            for field, value in updated_dto.__dict__.items():
                if hasattr(item, field) and value is not None:
                    setattr(item, field, value)

            # 更新修改时间（如有需求）
            item.modified_date = datetime.now()

            item.save()
            AntLogger.info(f"股票代码 {stock_code} 的记录已更新。")
        except DoesNotExist:
            AntLogger.info(f"未找到股票代码为 {stock_code} 的记录。")
        except Exception as e:
            AntLogger.info(f"更新记录时出错: {e}")

    def get_items_by_strategy_codes(
        self, strategy_codes: List[str]
    ) -> List[AntRiskAssessmentItem]:
        """
        根据多个策略代码查询风险评估记录，按照最终得分降序排序。
        """
        try:
            query = (
                AntRiskAssessmentItem.select()
                .where(AntRiskAssessmentItem.strategy_code.in_(strategy_codes))
                .order_by(AntRiskAssessmentItem.node_point.desc())
            )
            return list(query)
        except Exception as e:
            AntLogger.info(f"查询记录时出错: {e}")
            return []

    # 获取所有风险评估记录
    def get_all_risk_assessment_items(self) -> list[AntRiskAssessmentItemDto]:
        """
        获取所有风险评估记录
        :return: AntRiskAssessmentItemDto 对象列表
        """
        try:
            items = AntRiskAssessmentItem.select()
            return [
                AntRiskAssessmentItemDto(
                    stock_code=item.stock_code,
                    create_time=item.create_time,
                    description=item.description,
                    risk_type=item.risk_type,
                    risk_level=item.risk_level,
                    stock_tag_code=item.stock_tag_code,
                    strategy_code=item.strategy_code,
                    strategy_name=item.strategy_name,
                    strategy_group=item.strategy_group,
                    strategy_type=item.strategy_type,
                    analysis_day=item.analysis_day,
                    strategy_level=item.strategy_level,
                )
                for item in items
            ]
        except Exception as e:
            AntLogger.info(f"获取记录时出错: {e}")
            return []

    # 根据股票代码删除风险评估记录
    def delete_risk_assessment_item_by_code(self, stock_code: str):
        query = AntRiskAssessmentItem.delete().where(
            AntRiskAssessmentItem.stock_code == stock_code
        )
        # 执行删除操作，返回删除的行数
        deleted_rows = query.execute()

        if deleted_rows > 0:
            AntLogger.info
                f"股票代码 {stock_code} 的记录已全部删除，共删除 {deleted_rows} 条记录。"
            )
        else:
            AntLogger.info(f"未找到股票代码为 {stock_code} 的记录。")

    # 根据股票代码查询多条风险评估记录
    def query_risk_assessment_items_by_code(
        self, stock_code: str
    ) -> Optional[List[AntRiskAssessmentItemDto]]:
        """
        根据股票代码查询多条风险评估记录
        :param stock_code: 股票代码
        :return: 查询到的 AntRiskAssessmentItemDto 对象列表，若无记录则返回空列表
        """
        try:
            # 查询所有匹配的记录
            items = AntRiskAssessmentItem.select().where(
                AntRiskAssessmentItem.stock_code == stock_code
            )

            # 将查询结果转换为 AntRiskAssessmentItemDto 对象列表
            result = [
                AntRiskAssessmentItemDto(
                    stock_code=item.stock_code,
                    create_time=item.create_time,
                    description=item.description,
                    risk_type=item.risk_type,
                    risk_level=item.risk_level,
                    stock_tag_code=item.stock_tag_code,
                    strategy_code=item.strategy_code,
                    strategy_name=item.strategy_name,
                    strategy_group=item.strategy_group,
                    strategy_type=item.strategy_type,
                    analysis_day=item.analysis_day,
                    strategy_level=item.strategy_level,
                    node_point=item.node_point,
                )
                for item in items
            ]

            if not result:
                AntLogger.info(f"未找到股票代码为 {stock_code} 的记录。")

            return result
        except Exception as e:
            AntLogger.info(f"查询记录时出错: {e}")
            return None

    def get_top_n_items(self, n: int) -> List[AntRiskAssessmentItem]:
        """
        查询前 N 条风险评估记录，按最终得分降序排列。
        :param n: 需要查询的记录数量
        :return: 风险评估记录列表
        """
        try:
            query = (
                AntRiskAssessmentItem.select()
                .order_by(AntRiskAssessmentItem.node_point.desc())
                .limit(n)
            )
            return list(query)
        except Exception as e:
            AntLogger.info(f"查询前 {n} 条记录时出错: {e}")
            return []
